{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Type fields (refs) parsing"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Attempt to produce the info of `data.py` by parsing the C++ in `raw_header.h`.  \n",
    "This is very quick and dirty code, you have been warned."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 273,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "class RawClass\n",
      "  visit from name_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawPatchClass\n",
      "  visit from patched_class_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawFunction\n",
      "  visit from name_\n",
      "  parsing snapshot\n",
      "  visit to\n",
      "class RawClosureData\n",
      "  visit from context_scope_\n",
      "  visit to\n",
      "class RawSignatureData\n",
      "  visit from parent_function_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawRedirectionData\n",
      "  visit from type_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawFfiTrampolineData\n",
      "  visit from signature_type_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawField\n",
      "  visit from name_\n",
      "  parsing snapshot\n",
      "  visit to\n",
      "class RawScript\n",
      "  visit from url_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawLibrary\n",
      "  visit from name_\n",
      "  parsing snapshot\n",
      "  visit to\n",
      "class RawNamespace\n",
      "  visit from library_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawKernelProgramInfo\n",
      "  visit from string_offsets_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawCode\n",
      "  visit from object_pool_\n",
      "  visit to\n",
      "class RawBytecode\n",
      "  visit from object_pool_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawObjectPool\n",
      "class RawInstructions\n",
      "class RawPcDescriptors\n",
      "class RawCodeSourceMap\n",
      "class RawStackMap\n",
      "class RawLocalVarDescriptors\n",
      "  visit from names()[0]\n",
      "  visit to\n",
      "class RawExceptionHandlers\n",
      "  visit from handled_types_data_\n",
      "  visit to\n",
      "class RawContext\n",
      "  visit from parent_\n",
      "  visit to\n",
      "class RawContextScope\n",
      "class RawParameterTypeCheck\n",
      "  visit from param_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawSingleTargetCache\n",
      "  visit from target_\n",
      "  visit to\n",
      "class RawUnlinkedCall\n",
      "  visit from target_name_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawICData\n",
      "  visit from entries_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawMegamorphicCache\n",
      "  visit from buckets_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawSubtypeTestCache\n",
      "  visit from cache_\n",
      "  visit to\n",
      "class RawError\n",
      "class RawApiError\n",
      "  visit from message_\n",
      "  visit to\n",
      "class RawLanguageError\n",
      "  visit from previous_error_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawUnhandledException\n",
      "  visit from exception_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawUnwindError\n",
      "  visit from message_\n",
      "  visit to\n",
      "class RawInstance\n",
      "class RawLibraryPrefix\n",
      "  visit from name_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawTypeArguments\n",
      "  visit from instantiations_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawTypeRef\n",
      "  visit from type_test_stub_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawTypeParameter\n",
      "  visit from type_test_stub_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawClosure\n",
      "  visit from instantiator_type_arguments_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawNumber\n",
      "class RawInteger\n",
      "class RawSmi\n",
      "class RawMint\n",
      "class RawDouble\n",
      "class RawString\n",
      "  visit from length_\n",
      "  visit to\n",
      "class RawOneByteString\n",
      "class RawTwoByteString\n",
      "class RawTypedDataBase\n",
      "class RawTypedData\n",
      "  visit from length_\n",
      "  visit to\n",
      "class RawTypedDataView\n",
      "  visit from length_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawExternalOneByteString\n",
      "class RawExternalTwoByteString\n",
      "class RawBool\n",
      "class RawArray\n",
      "  visit from type_arguments_\n",
      "  visit to\n",
      "class RawImmutableArray\n",
      "class RawGrowableObjectArray\n",
      "  visit from type_arguments_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawLinkedHashMap\n",
      "  visit from type_arguments_\n",
      "  visit to\n",
      "class RawFloat32x4\n",
      "class RawInt32x4\n",
      "class RawFloat64x2\n",
      "class RawExternalTypedData\n",
      "  visit from length_\n",
      "  visit to\n",
      "class RawPointer\n",
      "  visit from type_arguments_\n",
      "  visit to\n",
      "class RawDynamicLibrary\n",
      "class RawCapability\n",
      "class RawSendPort\n",
      "class RawReceivePort\n",
      "  visit from send_port_\n",
      "  visit to\n",
      "class RawTransferableTypedData\n",
      "class RawStackTrace\n",
      "  visit from async_link_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawRegExp\n",
      "  visit from num_bracket_expressions_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawWeakProperty\n",
      "  visit from key_\n",
      "  visit to\n",
      "  parsing snapshot\n",
      "class RawMirrorReference\n",
      "  visit from referent_\n",
      "  visit to\n",
      "class RawUserTag\n",
      "  visit from label_\n",
      "  visit to\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "f = open('art-sdk/sdk/runtime/vm/raw_object.h')\n",
    "\n",
    "entries = []\n",
    "\n",
    "def try_to_parse_snapshot(f, l):\n",
    "    pref = '  RawObject** to_snapshot(Snapshot::Kind kind) {'\n",
    "    if not l.startswith(pref): return False\n",
    "    print('  parsing snapshot')\n",
    "    code = l[len(pref):]\n",
    "    outcode = ''\n",
    "    lev = 0\n",
    "    while True:\n",
    "        if len(code):\n",
    "            c = code[0]\n",
    "            code = code[1:]\n",
    "        else:\n",
    "            c = f.read(1)\n",
    "        if c == '{': lev += 1\n",
    "        elif c == '}':\n",
    "            if lev == 0: break\n",
    "            lev -= 1\n",
    "        outcode += c\n",
    "    entry['snapshot'] = outcode\n",
    "    return True\n",
    "\n",
    "last_class = None\n",
    "while True:\n",
    "    l = f.readline()\n",
    "    if not l: break\n",
    "\n",
    "    m = re.match('class (.+) :', l)\n",
    "    if m:\n",
    "        print('class', m.group(1))\n",
    "        last_class = m.group(1)\n",
    "        entry = None\n",
    "        continue\n",
    "\n",
    "    m = re.match(r'  VISIT_FROM\\((.+), (.+)\\)', l)\n",
    "    if m:\n",
    "        fi = m.group(2)\n",
    "        print('  visit from', fi)\n",
    "        if fi == 'names()[0]': fi = 'names_'\n",
    "        assert last_class.startswith('Raw') and fi.endswith('_')\n",
    "        entry = { 'kind': last_class[3:], 'from': fi[:-1] }\n",
    "        \n",
    "        fields = []\n",
    "        while True:\n",
    "            l = f.readline()\n",
    "            m = re.match(r'  VISIT_TO(_LENGTH)?\\((.+), (.+)\\)', l)\n",
    "            if m:\n",
    "                #fi = m.group(2)\n",
    "                print('  visit to')\n",
    "                #assert fi.endswith('_')\n",
    "                #entry['to'] = fi[:-1]\n",
    "                break\n",
    "            if try_to_parse_snapshot(f, l): continue\n",
    "            if l.startswith('#'): entry['has_preproc'] = True\n",
    "            fields.append(l)\n",
    "        entry['fields'] = fields\n",
    "        entries.append(entry)\n",
    "    \n",
    "    if try_to_parse_snapshot(f, l): continue"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 274,
   "metadata": {},
   "outputs": [],
   "source": [
    "snapshot_matcher = \\\n",
    "    re.escape('switch (kind) { case Snapshot::') + r'(\\w+)' + \\\n",
    "    re.escape(': return reinterpret_cast<RawObject**>(&ptr()->') + r'([a-zA-Z0-9_]+)_' + \\\n",
    "    re.escape('); case Snapshot::') + r'(\\w+)' + \\\n",
    "    re.escape(': return reinterpret_cast<RawObject**>(&ptr()->') + r'([a-zA-Z0-9_]+)_' + \\\n",
    "    re.escape('); case Snapshot::') + r'(\\w+)' + \\\n",
    "    re.escape(': return reinterpret_cast<RawObject**>(&ptr()->') + r'([a-zA-Z0-9_]+)_' + \\\n",
    "    re.escape('); case Snapshot::kMessage: case Snapshot::kNone: case Snapshot::kInvalid: break; } UNREACHABLE(); return NULL;')\n",
    "\n",
    "snapshot2_matcher = \\\n",
    "    re.escape('switch (kind) { case Snapshot::') + r'(\\w+)' + \\\n",
    "    re.escape(': return reinterpret_cast<RawObject**>(&ptr()->') + r'([a-zA-Z0-9_]+)_' + \\\n",
    "    re.escape('); case Snapshot::') + r'(\\w+)' + \\\n",
    "    re.escape(': case Snapshot::') + r'(\\w+)' + \\\n",
    "    re.escape(': return reinterpret_cast<RawObject**>(&ptr()->') + r'([a-zA-Z0-9_]+)_' + \\\n",
    "    re.escape('); case Snapshot::kMessage: case Snapshot::kNone: case Snapshot::kInvalid: break; } UNREACHABLE(); return NULL;')\n",
    "\n",
    "snapshot3_matcher = \\\n",
    "    re.escape('switch (kind) { case Snapshot::') + r'(\\w+)' + \\\n",
    "    re.escape(': case Snapshot::') + r'(\\w+)' + \\\n",
    "    re.escape(': return reinterpret_cast<RawObject**>(&ptr()->') + r'([a-zA-Z0-9_]+)_' + \\\n",
    "    re.escape('); case Snapshot::') + r'(\\w+)' + \\\n",
    "    re.escape(': return reinterpret_cast<RawObject**>(&ptr()->') + r'([a-zA-Z0-9_]+)_' + \\\n",
    "    re.escape('); case Snapshot::kMessage: case Snapshot::kNone: case Snapshot::kInvalid: break; } UNREACHABLE(); return NULL;')\n",
    "\n",
    "def parse_fields(fields):\n",
    "    fs = []\n",
    "    for f in fields:\n",
    "        if not f.split('//')[0].strip():\n",
    "            if len(fs) > 0 and (fs[-1][-1] != None):\n",
    "                i = f.find('//')\n",
    "                if i != -1: fs[-1][-1] += '\\n' + f[i+2:]\n",
    "            continue\n",
    "        m = re.fullmatch(r'Raw(\\w+)\\*\\s*([a-zA-Z0-9_]+)_\\;(\\s*//\\s*(.*))?', f.strip())\n",
    "        if not m:\n",
    "            #print(f)\n",
    "            return\n",
    "        fs.append([m.group(1), m.group(2), m.group(4)])\n",
    "    return fs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 275,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "skipping Function because of preproc\n",
      "skipping Field because of preproc\n",
      "skipping Code because of preproc\n",
      "skipping Bytecode because of preproc\n",
      "skipping LocalVarDescriptors because of non-matching fields\n",
      "skipping Context because of non-matching fields\n",
      "skipping ICData because of non-matching fields\n",
      "skipping TypeArguments because of non-matching fields\n",
      "skipping String because of preproc\n",
      "skipping TypedData because of non-matching fields\n",
      "skipping TypedDataView because of non-matching from\n",
      "skipping Array because of non-matching fields\n",
      "skipping ExternalTypedData because of non-matching fields\n",
      "skipping RegExp because of non-matching fields\n"
     ]
    }
   ],
   "source": [
    "fields = {}\n",
    "mappings = {}\n",
    "\n",
    "def parse_entry(e):\n",
    "    if 'has_preproc' in e:\n",
    "        print('skipping {} because of preproc'.format(e['kind']))\n",
    "        return\n",
    "    #print(e['kind'])\n",
    "    fs = parse_fields(e['fields'])\n",
    "    if not fs:\n",
    "        print('skipping {} because of non-matching fields'.format(e['kind']))\n",
    "        return\n",
    "    if e['from'] == 'type_test_stub':\n",
    "        fs.insert(0, ['Code', 'type_test_stub', None])\n",
    "    else:\n",
    "        #print(e['kind'], e['from'], fs[0] if len(fs) else None)\n",
    "        if len(fs) == 0 or e['from'] != fs[0][1]:\n",
    "            print('skipping {} because of non-matching from'.format(e['kind']))\n",
    "            return\n",
    "    \n",
    "    if 'snapshot' not in e:\n",
    "        mappings[e['kind']] = False\n",
    "    elif e['snapshot'].strip() == 'return to();' or e['snapshot'].strip() == 'return to()':\n",
    "        pass\n",
    "    elif e['snapshot'].strip() == 'return reinterpret_cast<RawObject**>(&ptr()->constants_table_);':\n",
    "        idx = next(filter(lambda x: x[1][1] == 'constants_table', enumerate(fs)))[0]\n",
    "        fs = fs[:idx+1]\n",
    "    else:\n",
    "        snapshot = re.sub(r'\\s+', ' ', e['snapshot'].strip())\n",
    "        m = re.fullmatch(snapshot_matcher, snapshot)\n",
    "        if m:\n",
    "            gr = m.groups()\n",
    "        else:\n",
    "            m = re.fullmatch(snapshot2_matcher, snapshot)\n",
    "            if m:\n",
    "                gr = list(m.groups())\n",
    "                gr.insert(3, gr[4])\n",
    "            else:\n",
    "                m = re.fullmatch(snapshot3_matcher, snapshot)\n",
    "                if m:\n",
    "                    gr = list(m.groups())\n",
    "                    gr.insert(1, gr[2])\n",
    "                else:\n",
    "                    print('Couldn\\'t match:', snapshot)\n",
    "                    return\n",
    "        gr = dict( gr[i*2:i*2+2] for i in range(len(gr) // 2) )\n",
    "        mappings[e['kind']] = ( gr['kFull'], gr['kFullJIT'], gr['kFullAOT'] )\n",
    "    fields[e['kind']] = fs\n",
    "\n",
    "for e in entries: parse_entry(e)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 276,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    'Class': [\n",
      "        ['String', 'name', None],\n",
      "        ['String', 'user_name', None],\n",
      "        ['Array', 'functions', None],\n",
      "        ['Array', 'functions_hash_table', None],\n",
      "        ['Array', 'fields', None],\n",
      "        ['Array', 'offset_in_words_to_field', None],\n",
      "        ['Array', 'interfaces', 'Array of AbstractType.'],\n",
      "        ['Script', 'script', None],\n",
      "        ['Library', 'library', None],\n",
      "        ['TypeArguments', 'type_parameters', 'Array of TypeParameter.'],\n",
      "        ['AbstractType', 'super_type', None],\n",
      "        ['Function', 'signature_function', 'Associated function for typedef class.'],\n",
      "        ['Array', 'constants', 'Canonicalized const instances of this class.'],\n",
      "        ['Type', 'declaration_type', 'Declaration type for this class.'],\n",
      "        ['Array', 'invocation_dispatcher_cache', 'Cache for dispatcher functions.'],\n",
      "        ['Code', 'allocation_stub', 'Stub code for allocation of instances.'],\n",
      "        ['GrowableObjectArray', 'direct_implementors', 'Array of Class.'],\n",
      "        ['GrowableObjectArray', 'direct_subclasses', 'Array of Class.'],\n",
      "        ['Array', 'dependent_code', 'CHA optimized codes.'],\n",
      "    ],\n",
      "    'PatchClass': [\n",
      "        ['Class', 'patched_class', None],\n",
      "        ['Class', 'origin_class', None],\n",
      "        ['Script', 'script', None],\n",
      "        ['ExternalTypedData', 'library_kernel_data', None],\n",
      "    ],\n",
      "    'ClosureData': [\n",
      "        ['ContextScope', 'context_scope', None],\n",
      "        ['Function', 'parent_function', 'Enclosing function of this local function.'],\n",
      "        ['Type', 'signature_type', None],\n",
      "        ['Instance', 'closure', 'Closure object for static implicit closures.'],\n",
      "    ],\n",
      "    'SignatureData': [\n",
      "        ['Function', 'parent_function', 'Enclosing function of this sig. function.'],\n",
      "        ['Type', 'signature_type', None],\n",
      "    ],\n",
      "    'RedirectionData': [\n",
      "        ['Type', 'type', None],\n",
      "        ['String', 'identifier', None],\n",
      "        ['Function', 'target', None],\n",
      "    ],\n",
      "    'FfiTrampolineData': [\n",
      "        ['Type', 'signature_type', None],\n",
      "        ['Function', 'c_signature', None],\n",
      "        ['Function', 'callback_target', None],\n",
      "        ['Instance', 'callback_exceptional_return', None],\n",
      "    ],\n",
      "    'Script': [\n",
      "        ['String', 'url', None],\n",
      "        ['String', 'resolved_url', None],\n",
      "        ['Array', 'compile_time_constants', None],\n",
      "        ['TypedData', 'line_starts', None],\n",
      "        ['Array', 'debug_positions', None],\n",
      "        ['Array', 'yield_positions', None],\n",
      "        ['KernelProgramInfo', 'kernel_program_info', None],\n",
      "        ['String', 'source', None],\n",
      "    ],\n",
      "    'Library': [\n",
      "        ['String', 'name', None],\n",
      "        ['String', 'url', None],\n",
      "        ['String', 'private_key', None],\n",
      "        ['Array', 'dictionary', 'Top-level names in this library.'],\n",
      "        ['GrowableObjectArray', 'metadata', 'Metadata on classes, methods etc.'],\n",
      "        ['Class', 'toplevel_class', 'Class containing top-level elements.'],\n",
      "        ['GrowableObjectArray', 'owned_scripts', None],\n",
      "        ['Array', 'imports', 'List of Namespaces imported without prefix.'],\n",
      "        ['Array', 'exports', 'List of re-exported Namespaces.'],\n",
      "        ['Instance', 'load_error', 'Error iff load_state_ == kLoadError.'],\n",
      "        ['ExternalTypedData', 'kernel_data', None],\n",
      "        ['Array', 'resolved_names', 'Cache of resolved names in library scope.'],\n",
      "        ['Array', 'exported_names', 'Cache of exported names by library.'],\n",
      "        ['Array', 'loaded_scripts', 'Array of scripts loaded in this library.'],\n",
      "    ],\n",
      "    'Namespace': [\n",
      "        ['Library', 'library', 'library with name dictionary.'],\n",
      "        ['Array', 'show_names', 'list of names that are exported.'],\n",
      "        ['Array', 'hide_names', 'blacklist of names that are not exported.'],\n",
      "        ['Field', 'metadata_field', 'remembers the token pos of metadata if any,\\n and the metadata values if computed.\\n'],\n",
      "    ],\n",
      "    'KernelProgramInfo': [\n",
      "        ['TypedData', 'string_offsets', None],\n",
      "        ['ExternalTypedData', 'string_data', None],\n",
      "        ['TypedData', 'canonical_names', None],\n",
      "        ['ExternalTypedData', 'metadata_payloads', None],\n",
      "        ['ExternalTypedData', 'metadata_mappings', None],\n",
      "        ['Array', 'scripts', None],\n",
      "        ['Array', 'constants', None],\n",
      "        ['Array', 'bytecode_component', None],\n",
      "        ['GrowableObjectArray', 'potential_natives', None],\n",
      "        ['GrowableObjectArray', 'potential_pragma_functions', None],\n",
      "        ['ExternalTypedData', 'constants_table', None],\n",
      "    ],\n",
      "    'ExceptionHandlers': [\n",
      "        ['Array', 'handled_types_data', None],\n",
      "    ],\n",
      "    'ParameterTypeCheck': [\n",
      "        ['AbstractType', 'param', None],\n",
      "        ['AbstractType', 'type_or_bound', None],\n",
      "        ['String', 'name', None],\n",
      "        ['SubtypeTestCache', 'cache', None],\n",
      "    ],\n",
      "    'SingleTargetCache': [\n",
      "        ['Code', 'target', None],\n",
      "    ],\n",
      "    'UnlinkedCall': [\n",
      "        ['String', 'target_name', None],\n",
      "        ['Array', 'args_descriptor', None],\n",
      "    ],\n",
      "    'MegamorphicCache': [\n",
      "        ['Array', 'buckets', None],\n",
      "        ['Smi', 'mask', None],\n",
      "        ['String', 'target_name', 'Name of target function.'],\n",
      "        ['Array', 'args_descriptor', 'Arguments descriptor.'],\n",
      "    ],\n",
      "    'SubtypeTestCache': [\n",
      "        ['Array', 'cache', None],\n",
      "    ],\n",
      "    'ApiError': [\n",
      "        ['String', 'message', None],\n",
      "    ],\n",
      "    'LanguageError': [\n",
      "        ['Error', 'previous_error', 'May be null.'],\n",
      "        ['Script', 'script', None],\n",
      "        ['String', 'message', None],\n",
      "        ['String', 'formatted_message', \"Incl. previous error's formatted message.\"],\n",
      "    ],\n",
      "    'UnhandledException': [\n",
      "        ['Instance', 'exception', None],\n",
      "        ['Instance', 'stacktrace', None],\n",
      "    ],\n",
      "    'UnwindError': [\n",
      "        ['String', 'message', None],\n",
      "    ],\n",
      "    'LibraryPrefix': [\n",
      "        ['String', 'name', 'Library prefix name.'],\n",
      "        ['Library', 'importer', 'Library which declares this prefix.'],\n",
      "        ['Array', 'imports', 'Libraries imported with this prefix.'],\n",
      "        ['Array', 'dependent_code', 'Code that refers to deferred, unloaded\\n library prefix.\\n'],\n",
      "    ],\n",
      "    'TypeRef': [\n",
      "        ['Code', 'type_test_stub', None],\n",
      "        ['AbstractType', 'type', 'The referenced type.'],\n",
      "    ],\n",
      "    'TypeParameter': [\n",
      "        ['Code', 'type_test_stub', None],\n",
      "        ['String', 'name', None],\n",
      "        ['Smi', 'hash', None],\n",
      "        ['AbstractType', 'bound', 'ObjectType if no explicit bound specified.'],\n",
      "        ['Function', 'parameterized_function', None],\n",
      "    ],\n",
      "    'Closure': [\n",
      "        ['TypeArguments', 'instantiator_type_arguments', None],\n",
      "        ['TypeArguments', 'function_type_arguments', None],\n",
      "        ['TypeArguments', 'delayed_type_arguments', None],\n",
      "        ['Function', 'function', None],\n",
      "        ['Context', 'context', None],\n",
      "        ['Smi', 'hash', None],\n",
      "    ],\n",
      "    'GrowableObjectArray': [\n",
      "        ['TypeArguments', 'type_arguments', None],\n",
      "        ['Smi', 'length', None],\n",
      "        ['Array', 'data', None],\n",
      "    ],\n",
      "    'LinkedHashMap': [\n",
      "        ['TypeArguments', 'type_arguments', None],\n",
      "        ['TypedData', 'index', None],\n",
      "        ['Smi', 'hash_mask', None],\n",
      "        ['Array', 'data', None],\n",
      "        ['Smi', 'used_data', None],\n",
      "        ['Smi', 'deleted_keys', None],\n",
      "    ],\n",
      "    'Pointer': [\n",
      "        ['TypeArguments', 'type_arguments', None],\n",
      "        ['Integer', 'c_memory_address', None],\n",
      "    ],\n",
      "    'ReceivePort': [\n",
      "        ['SendPort', 'send_port', None],\n",
      "        ['Instance', 'handler', None],\n",
      "    ],\n",
      "    'StackTrace': [\n",
      "        ['StackTrace', 'async_link', 'Link to parent async stack trace.'],\n",
      "        ['Array', 'code_array', 'Code object for each frame in the stack trace.'],\n",
      "        ['Array', 'pc_offset_array', 'Offset of PC for each frame.'],\n",
      "    ],\n",
      "    'WeakProperty': [\n",
      "        ['Object', 'key', None],\n",
      "        ['Object', 'value', None],\n",
      "    ],\n",
      "    'MirrorReference': [\n",
      "        ['Object', 'referent', None],\n",
      "    ],\n",
      "    'UserTag': [\n",
      "        ['String', 'label', None],\n",
      "    ],\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def format_fields(fs):\n",
    "    return \"\".join(\"        {},\\n\".format(repr(x)) for x in fs)\n",
    "def format_type(e):\n",
    "    return '    {}: [\\n{}    ],\\n'.format(repr(e[0]), format_fields(e[1]))\n",
    "print(\"\".join(format_type(e) for e in fields.items()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Results & manual parsing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 277,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Class', 'object_class', None],\n",
      "        ['Type', 'object_type', None],\n",
      "        ['Class', 'null_class', None],\n",
      "        ['Type', 'null_type', None],\n",
      "        ['Type', 'function_type', None],\n",
      "        ['Type', 'type_type', None],\n",
      "        ['Class', 'closure_class', None],\n",
      "        ['Type', 'number_type', None],\n",
      "        ['Type', 'int_type', None],\n",
      "        ['Class', 'integer_implementation_class', None],\n",
      "        ['Type', 'int64_type', None],\n",
      "        ['Class', 'smi_class', None],\n",
      "        ['Type', 'smi_type', None],\n",
      "        ['Class', 'mint_class', None],\n",
      "        ['Type', 'mint_type', None],\n",
      "        ['Class', 'double_class', None],\n",
      "        ['Type', 'double_type', None],\n",
      "        ['Type', 'float32x4_type', None],\n",
      "        ['Type', 'int32x4_type', None],\n",
      "        ['Type', 'float64x2_type', None],\n",
      "        ['Type', 'string_type', None],\n",
      "        ['TypeArguments', 'type_argument_int', None],\n",
      "        ['TypeArguments', 'type_argument_double', None],\n",
      "        ['TypeArguments', 'type_argument_string', None],\n",
      "        ['TypeArguments', 'type_argument_string_dynamic', None],\n",
      "        ['TypeArguments', 'type_argument_string_string', None],\n",
      "        ['Class', 'compiletime_error_class', None],\n",
      "        ['Class', 'pragma_class', None],\n",
      "        ['Field', 'pragma_name', None],\n",
      "        ['Field', 'pragma_options', None],\n",
      "        ['Class', 'future_class', None],\n",
      "        ['Class', 'completer_class', None],\n",
      "        ['Class', 'symbol_class', None],\n",
      "        ['Class', 'one_byte_string_class', None],\n",
      "        ['Class', 'two_byte_string_class', None],\n",
      "        ['Class', 'external_one_byte_string_class', None],\n",
      "        ['Class', 'external_two_byte_string_class', None],\n",
      "        ['Type', 'bool_type', None],\n",
      "        ['Class', 'bool_class', None],\n",
      "        ['Class', 'array_class', None],\n",
      "        ['Type', 'array_type', None],\n",
      "        ['Class', 'immutable_array_class', None],\n",
      "        ['Class', 'growable_object_array_class', None],\n",
      "        ['Class', 'linked_hash_map_class', None],\n",
      "        ['Class', 'linked_hash_set_class', None],\n",
      "        ['Class', 'float32x4_class', None],\n",
      "        ['Class', 'int32x4_class', None],\n",
      "        ['Class', 'float64x2_class', None],\n",
      "        ['Class', 'error_class', None],\n",
      "        ['Class', 'weak_property_class', None],\n",
      "        ['Array', 'symbol_table', None],\n",
      "        ['Array', 'canonical_types', None],\n",
      "        ['Array', 'canonical_type_arguments', None],\n",
      "        ['Library', 'async_library', None],\n",
      "        ['Library', 'builtin_library', None],\n",
      "        ['Library', 'core_library', None],\n",
      "        ['Library', 'collection_library', None],\n",
      "        ['Library', 'convert_library', None],\n",
      "        ['Library', 'developer_library', None],\n",
      "        ['Library', 'ffi_library', None],\n",
      "        ['Library', '_internal_library', None],\n",
      "        ['Library', 'isolate_library', None],\n",
      "        ['Library', 'math_library', None],\n",
      "        ['Library', 'mirrors_library', None],\n",
      "        ['Library', 'native_wrappers_library', None],\n",
      "        ['Library', 'profiler_library', None],\n",
      "        ['Library', 'root_library', None],\n",
      "        ['Library', 'typed_data_library', None],\n",
      "        ['Library', '_vmservice_library', None],\n",
      "        ['GrowableObjectArray', 'libraries', None],\n",
      "        ['Array', 'libraries_map', None],\n",
      "        ['GrowableObjectArray', 'closure_functions', None],\n",
      "        ['GrowableObjectArray', 'pending_classes', None],\n",
      "        ['GrowableObjectArray', 'pending_unevaluated_const_fields', None],\n",
      "        ['GrowableObjectArray', 'pending_deferred_loads', None],\n",
      "        ['GrowableObjectArray', 'resume_capabilities', None],\n",
      "        ['GrowableObjectArray', 'exit_listeners', None],\n",
      "        ['GrowableObjectArray', 'error_listeners', None],\n",
      "        ['Instance', 'stack_overflow', None],\n",
      "        ['Instance', 'out_of_memory', None],\n",
      "        ['UnhandledException', 'preallocated_unhandled_exception', None],\n",
      "        ['StackTrace', 'preallocated_stack_trace', None],\n",
      "        ['Function', 'lookup_port_handler', None],\n",
      "        ['Function', 'handle_message_function', None],\n",
      "        ['Function', 'growable_list_factory', None],\n",
      "        ['Function', 'simple_instance_of_function', None],\n",
      "        ['Function', 'simple_instance_of_true_function', None],\n",
      "        ['Function', 'simple_instance_of_false_function', None],\n",
      "        ['Function', 'async_clear_thread_stack_trace', None],\n",
      "        ['Function', 'async_set_thread_stack_trace', None],\n",
      "        ['Function', 'async_star_move_next_helper', None],\n",
      "        ['Function', 'complete_on_async_return', None],\n",
      "        ['Class', 'async_star_stream_controller', None],\n",
      "        ['ObjectPool', 'global_object_pool', None],\n",
      "        ['Array', 'library_load_error_table', None],\n",
      "        ['Array', 'unique_dynamic_targets', None],\n",
      "        ['GrowableObjectArray', 'megamorphic_cache_table', None],\n",
      "        ['Code', 'build_method_extractor_code', None],\n",
      "        ['Code', 'null_error_stub_with_fpu_regs_stub', None],\n",
      "        ['Code', 'null_error_stub_without_fpu_regs_stub', None],\n",
      "        ['Code', 'stack_overflow_stub_with_fpu_regs_stub', None],\n",
      "        ['Code', 'stack_overflow_stub_without_fpu_regs_stub', None],\n",
      "        ['Code', 'write_barrier_wrappers_stub', None],\n",
      "        ['Code', 'array_write_barrier_stub', None],\n",
      "        ['Code', 'megamorphic_miss_code', None],\n",
      "        ['Function', 'megamorphic_miss_function', None],\n",
      "        ['Array', 'code_order_table', None],\n",
      "        ['Array', 'obfuscation_map', None],\n",
      "        ['GrowableObjectArray', 'changed_in_last_reload', None],\n",
      "        ['Class', 'ffi_pointer_class', None],\n",
      "        ['Class', 'ffi_native_type_class', None],\n",
      "        ['Class', 'ffi_struct_class', None],\n",
      "        ['Object', 'ffi_as_function_internal', None],\n",
      "\n"
     ]
    }
   ],
   "source": [
    "import subprocess\n",
    "import yapf\n",
    "\n",
    "x = subprocess.check_output('xclip -sel clip -o', shell=True).decode()\n",
    "fs = parse_fields(x.splitlines())\n",
    "\n",
    "#subprocess.check_output('xclip -sel clip', shell=True, input=l.lstrip().encode())\n",
    "print(format_fields(fs).lstrip())"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
